package org.iabako.shared.entity.business;

import com.google.gwt.user.client.rpc.GwtTransient;
import org.hibernate.annotations.Index;
import org.iabako.client.ui.layout.field.InputTextEmail;
import org.iabako.shared.entity.enumeration.FinancialStatusClient;
import org.iabako.shared.entity.enumeration.Gender;
import org.iabako.shared.entity.user.Enterprise;
import org.iabako.shared.entity.user.User;
import org.iabako.shared.tools.GenericTools;

import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Date: 22/09/13
 * Time: 18:19
 */

@Entity
@Table(name = "CLIENT")
public class Client extends BusinessEntity implements PaymentsOwner {

    @Id
    @GeneratedValue
    @Column(name = "ID")
    private Long id;

    @Column(name = "NUMBER", nullable = false)
    @Index(name = "NUMBER")
    @NotNull
    private String number;

    @Column(name = "FIRST_NAME")
    @Index(name = "FIRST_NAME")
    private String firstName;

    @Column(name = "LAST_NAME")
    @Index(name = "LAST_NAME")
    private String lastName;

    @Column(name = "NAME", nullable = false)
    @Index(name = "NAME")
    @NotNull
    private String name;

    @Column(name = "GENDER", nullable = false)
    @Enumerated(EnumType.STRING)
    @NotNull
    private Gender gender;

    @Column(name = "BIRTHDAY")
    @Temporal(value = TemporalType.DATE)
    @Past(message = "server_validation_birthday_must_be_in_past")
    private Date birthday;

    @Column(name = "EMAIL")
    @Index(name = "EMAIL")
    @Pattern(regexp = InputTextEmail.EMAIL_PATTERN, message = "server_validation_email_pattern")
    private String email;

    @Embedded
    @Valid
    private Address address;

    @Column(name = "PHONE_NUMBER1")
    @Index(name = "PHONE_NUMBER1")
    private String phoneNumber1;

    @Column(name = "PHONE_NUMBER2")
    private String phoneNumber2;

    //Start company contact fields
    @Column(name = "CONTACT_POSITION")
    private String contactPosition;

    @Column(name = "CONTACT_NAME")
    private String contactName;

    @Column(name = "CONTACT_EMAIL")
    @Pattern(regexp = InputTextEmail.EMAIL_PATTERN, message = "server_validation_email_pattern")
    private String contactEmail;

    @Column(name = "CONTACT_PHONE_NUMBER1")
    private String contactPhoneNumber1;

    @Column(name = "CONTACT_PHONE_NUMBER2")
    private String contactPhoneNumber2;
    //End company contact fields

    @Column(name = "STATUS", nullable = false)
    @Index(name = "STATUS")
    @Enumerated(EnumType.STRING)
    @NotNull
    private FinancialStatusClient status;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_ENTERPRISE", nullable = false)
    @GwtTransient
    private Enterprise enterprise;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "client")
    //To Avoid serializing exception in lazy/proxy objects.
    @GwtTransient
    private List<CustomFieldValue> customFieldValues;

    //For ClientSearch filtering by pending conversations
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "client")
    //To Avoid serializing exception in lazy/proxy objects.
    @GwtTransient
    private List<ClientConversation> conversations;

    @Column(name = "DISABLED")
    private boolean disabled;

    @Column(name = "EXTERNAL_LINK_NAME")
    private String externalLinkName;

    @Column(name = "EXTERNAL_LINK_URL")
    private String externalLinkUrl;

    @Column(name = "CREATION_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate;

    @Column(name = "LAST_MODIFICATION_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModificationDate;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_LAST_MODIFICATION_USER")
    @GwtTransient
    private User lastModificationUser;

    //For GWT client side use to avoid timezone conversions
    @Transient
    private String birthdayString;

    public Client() {
        status = FinancialStatusClient._3_OK;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getName() {
        if (gender != Gender.company && (firstName != null || lastName != null)) {
            name = firstName != null ? firstName + " " : "";
            name += lastName != null ? lastName.toUpperCase() : "";
            name = name.trim();
        }
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getBirthdayString() {
        if (birthdayString == null) {
            birthdayString = GenericTools.formatDateToString(birthday);
        }
        return birthdayString;
    }

    public void setBirthdayString(String birthdayString) {
        this.birthdayString = birthdayString;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String getPhoneNumber1() {
        return phoneNumber1;
    }

    public void setPhoneNumber1(String phoneNumber1) {
        this.phoneNumber1 = phoneNumber1;
    }

    public String getPhoneNumber2() {
        return phoneNumber2;
    }

    public void setPhoneNumber2(String phoneNumber2) {
        this.phoneNumber2 = phoneNumber2;
    }

    public String getContactPosition() {
        return contactPosition;
    }

    public void setContactPosition(String contactPosition) {
        this.contactPosition = contactPosition;
    }

    public String getContactName() {
        return contactName;
    }

    public void setContactName(String contactName) {
        this.contactName = contactName;
    }

    public String getContactEmail() {
        return contactEmail;
    }

    public void setContactEmail(String contactEmail) {
        this.contactEmail = contactEmail;
    }

    public String getContactPhoneNumber1() {
        return contactPhoneNumber1;
    }

    public void setContactPhoneNumber1(String contactPhoneNumber1) {
        this.contactPhoneNumber1 = contactPhoneNumber1;
    }

    public String getContactPhoneNumber2() {
        return contactPhoneNumber2;
    }

    public void setContactPhoneNumber2(String contactPhoneNumber2) {
        this.contactPhoneNumber2 = contactPhoneNumber2;
    }

    public FinancialStatusClient getStatus() {
        return status;
    }

    public void setStatus(FinancialStatusClient status) {
        this.status = status;
    }

    public Enterprise getEnterprise() {
        return enterprise;
    }

    public void setEnterprise(Enterprise enterprise) {
        this.enterprise = enterprise;
    }

    public List<CustomFieldValue> getCustomFieldValues() {
        if (customFieldValues == null) {
            customFieldValues = new ArrayList<CustomFieldValue>();
        }
        return customFieldValues;
    }

    public List<ClientConversation> getConversations() {
        return conversations;
    }

    public void setConversations(List<ClientConversation> conversations) {
        this.conversations = conversations;
    }

    public void setCustomFieldValues(List<CustomFieldValue> customFieldValues) {
        this.customFieldValues = customFieldValues;
    }

    public boolean isDisabled() {
        return disabled;
    }

    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    public String getExternalLinkName() {
        return externalLinkName;
    }

    public void setExternalLinkName(String externalLinkName) {
        this.externalLinkName = externalLinkName;
    }

    public String getExternalLinkUrl() {
        return externalLinkUrl;
    }

    public void setExternalLinkUrl(String externalLinkUrl) {
        this.externalLinkUrl = externalLinkUrl;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public Date getLastModificationDate() {
        return lastModificationDate;
    }

    public void setLastModificationDate(Date lastModificationDate) {
        this.lastModificationDate = lastModificationDate;
    }

    public User getLastModificationUser() {
        return lastModificationUser;
    }

    public void setLastModificationUser(User lastModificationUser) {
        this.lastModificationUser = lastModificationUser;
    }

    @Transient
    @Override
    public void copyDatesAsString() {
        getBirthdayString();
    }
}
